<?php

namespace App\Http\Model;

use App\Http\Services\BoardExtendServices;
use App\Http\Services\MaximumGoldRoomServices;
use App\Http\Services\RoomMsgServices;
use App\Lib\Publisher;
use App\Lib\Snowflake\SnowflakeGenerator;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;


class FinanceCharm extends Base
{
    protected $table = 'finance_charm_stream';
    protected $tablePrefix = '';
    public $timestamps = false;

    private $redis_charts_user_charm_day = "FINANCE:CHARTS:USER:CHARM:DAY:"; // FINANCE:CHARTS:USER:CHARM:DAY:2018-11-22
    private $redis_charts_user_charm_week = "FINANCE:CHARTS:USER:CHARM:WEEK:"; // FINANCE:CHARTS:USER:CHARM:DAY:2018-11-222018-11-20
    private $redis_charts_user_charm_month = "FINANCE:CHARTS:USER:CHARM:MONTH:"; // FINANCE:CHARTS:USER:CHARM:DAY:2018-11
    private $redis_charts_user_charm_all = "FINANCE:CHARTS:USER:CHARM:ALL";
    // 房间个人人气榜&最多金个人气榜 & 平台人气榜
    private $redis_charts_room_user_charm_day = "FINANCE:CHARTS:ROOM:USER:CHARM:DAY:"; // FINANCE:CHARTS:ROOM:USER:CHARM:DAY:{room_id}:{ymd}
    private $redis_charts_room_user_charts_yestorday = "FINANCE:CHARTS:ROOM:USER:CHARM:YESTORDAY:"; // FINANCE:CHARTS:ROOM:USER:CHARM:DAY:{room_id}:{ymd}
    private $redis_charts_room_user_charts_lastweek = "FINANCE:CHARTS:ROOM:USER:CHARM:LASTWEEK:";
    private $redis_charts_room_user_charm_week = "FINANCE:CHARTS:ROOM:USER:CHARM:WEEK:"; // FINANCE:CHARTS:ROOM:USER:CHARM:WEEK:{room_id}:{ymd}:{ymd}
    private $redis_charts_room_user_charm_month = "FINANCE:CHARTS:ROOM:USER:CHARM:MONTH:"; // FINANCE:CHARTS:ROOM:USER:CHARM:DAY:{room_id}-2018-11
    private $redis_charts_room_user_charm_all = "FINANCE:CHARTS:ROOM:USER:CHARM:ALL:"; // FINANCE:CHARTS:ROOM:USER:CHARM:ALL:{room_id}

    private $redis_cache_finance_user_wallet = "CACHE:FINANCE:USER:WALLET";

    private $redis_cache_finance_charm_log = "CACHE:FINANCE:CHARM:LOG";
    private $redis_cache_finance_charm_hset = "CACHE:FINANCE:CHARM:HSET";

    private $redis_cache_finance_room_wallet = "CACHE:FINANCE:ROOM:WALLET";

    private $redis_finance_user_charm_rank = "FINANCE:USER:CHARM:RANK";

    private $redis_finance_user_charm_before_total = 'FINANCE:CHARTS:USER:CHARM:BEFORE:TOTAL';
    private $redis_finance_user_charm_total = 'FINANCE:CHARTS:USER:CHARM:TOTAL';

    private $redis_charts_user_charm_day_maximum_gold = "FINANCE:CHARTS:USER:CHARM:DAY:MAXIMUM:GOLD:"; // FINANCE:CHARTS:USER:CHARM:DAY:MAXIMUM:GOLD:2018-11-22
    private $redis_charts_user_charm_week_maximum_gold = "FINANCE:CHARTS:USER:CHARM:WEEK:MAXIMUM:GOLD:"; // FINANCE:CHARTS:USER:CHARM:DAY:MAXIMUM:GOLD:2018-11-222018-11-20
    private $redis_charts_user_charm_month_maximum_gold = "FINANCE:CHARTS:USER:CHARM:MONTH:MAXIMUM:GOLD:"; // FINANCE:CHARTS:USER:CHARM:DAY:MAXIMUM:GOLD:2018-11
    private $redis_charts_user_charm_all_maximum_gold = "FINANCE:CHARTS:USER:CHARM:ALL:MAXIMUM:GOLD";

    ##  zb_finance_charm_stream.charm_type 魅力值流水类型   -1.金豆礼物 0.钻石礼物、1.守护、2.商品、3.提现、4.提现驳回 13.开箱子 20.任务奖励 21.金豆礼物
    const FINANCE_CHARM_PEARL = 21; //金豆（珍珠）

    public function __construct(array $attributes = [])
    {
        $this->tablePrefix = env('DB_PREFIX');
        parent::__construct($this->table, $attributes);
    }

    //魅力值明细
    public function getCharmListData($userId, $page, $page_size)
    {
        $condition = ['user_id' => $userId];
        $fields = ['charm_type', 'charm_desc', 'charm_value', 'change_timestamp'];
        $document = DB::table($this->table)
            ->where($condition)
            ->orderBy('change_timestamp', 'desc')
            ->offset(($page) * $page_size)
            ->limit($page_size)
            ->get($fields);

        $result = self::objToArray($document);

        return $result;
    }

    /**
     * 更新用户魅力值
     * @param int $user_id 更改该user_id的魅力值
     * @param int $from_user_id 来源于哪个user_id
     * @param int $room_id 房间id
     * @param int $charm_type -1.金豆礼物 0.钻石礼物、1.守护、2.商品、3.提现、4.提现驳回 13.开箱子 20.任务奖励 21.金豆礼物 99.比心（计时）礼物
     * @param int $charm_value 支出使用负数
     * @param string $charm_desc 描述
     * @return bool
     */
    public function inc($user_id, $from_user_id, $room_id, $charm_type, $charm_value, $charm_desc, $TimedGoodsScore = 0, $gift_stream_id = 0)
    {
        if (empty($user_id) || empty($charm_value) || $charm_value < 1) {
            return true;
        }
        DB::table("finance_wallet")
            ->where('user_id', '=', $user_id)
            ->increment('charm_balance', $charm_value, ['change_timestamp' => time()]);

        $wallet = DB::table('finance_wallet')
            ->where('user_id', '=', $user_id)
            ->first(['charm_balance']);

        $log_id = DB::table("finance_charm_stream")->insertGetId([
            "gift_stream_id" => $gift_stream_id,
            "user_id" => $user_id,
            "room_id" => $room_id,
            "charm_value" => $charm_value,
            "from_user_id" => $from_user_id,
            "charm_type" => $charm_type,
            "charm_desc" => $charm_desc,
            "charm_balance" => $wallet->charm_balance,
            "change_timestamp" => time()
        ]);
        Redis::DEL($this->redis_cache_finance_user_wallet . ':' . $user_id);

        $this->inc_charts($user_id, $charm_value, $room_id, $charm_type, $TimedGoodsScore, $log_id);
        return true;
    }


    public function getCharmLogList($userId, $roomId, $pagesize = 10, $page = 0)
    {
        $list = [];
        $maxStreamId = Redis::HGET($this->redis_cache_finance_charm_hset . ":$roomId", $userId);
        write_log('max',$maxStreamId,[]);
        try {
            // write_log("finance", "zq-get-charm-log", [$maxStreamId]);
            if ($maxStreamId) {
                $list = DB::table('finance_charm_stream')->join('user', 'finance_charm_stream.from_user_id', '=', 'user.user_id')
                    ->where('finance_charm_stream.user_id', '=', $userId)
                    ->where('finance_charm_stream.room_id', '=', $roomId)
                    ->select('finance_charm_stream.*', 'user.uuid as from_user_uuid', 'user.nickname as from_user_nickname', 'user.portrait as from_user_portrait', 'user.gender as from_user_gender')
                    ->selectRaw('sum(zb_finance_charm_stream.charm_value) as all_charm_value')
                    ->where('stream_id', ">", $maxStreamId)->limit($pagesize)->groupBy(['finance_charm_stream.from_user_id'])->orderBy('stream_id', 'desc')->offset($page * $pagesize)->get();
            } else {
                $list = DB::table('finance_charm_stream')->join('user', 'finance_charm_stream.from_user_id', '=', 'user.user_id')
                    ->where('finance_charm_stream.user_id', '=', $userId)
                    ->where('finance_charm_stream.room_id', '=', $roomId)
                    ->select('finance_charm_stream.*','user.uuid as from_user_uuid', 'user.nickname as from_user_nickname', 'user.portrait as from_user_portrait', 'user.gender as from_user_gender')
                    ->selectRaw('sum(zb_finance_charm_stream.charm_value) as all_charm_value')
                    ->limit($pagesize)->offset($page * $pagesize)->groupBy(['finance_charm_stream.from_user_id'])->orderBy('stream_id', 'desc')->get();
            }
//            write_log("finance", "zq-get-charm-log", [$list]);
            foreach ($list as $key => $value) {
                $images_arr = json_decode($value->from_user_portrait, true) ?? [];
                $list[$key]->from_user_adapt_images = empty($images_arr) ? [] : build_adapt_images($images_arr, 480)[0];
                unset($list[$key]->from_user_portrait);
//                write_log("finance", "zq-get-charm-log", [$value]);
            }
        } catch (\Exception $e) {
//            write_log("finance", "zq-get-charm-log-error", [$e->getMessage()]);
        }

        return $list;
    }

    public function clearCharmLog($userId, $roomId)
    {
        try {
            $model = new \app\Http\Model\FinanceCharm();
            $maxStreamId = $model->where('user_id', '=', $userId)->where('room_id', '=', $roomId)->max('stream_id');
            $maxStreamId = $maxStreamId ?? 0;
            Redis::HSET($this->redis_cache_finance_charm_hset . ":$roomId", $userId, $maxStreamId);
        } catch (\Exception $e) {
            write_log("finance", "zq-clear-charm-log-error", [$e->getMessage()]);
        }
    }
    /**
     * 更新榜单数据
     *  平台人气榜-个人
     *  最多金榜 -个人
     * @param $user_id
     * @param $charm_value
     * @param $room_id
     * @param int $charm_type
     * @return bool
     */
    private function inc_charts($user_id, $charm_value, $room_id, $charm_type = 0, $TimedGoodsScore = 0, $log_id = 0)
    {
        write_log("finance", "inc-charts-" . $room_id, [$user_id, $charm_value, $room_id, $charm_type]);
        if (empty($charm_value) || $charm_value < 1) {
            return true;
        }
        $now = time();
        //今日
        $ymdNow = date("Ymd", $now);
        //周一
        $weekSt = date("Ymd", strtotime('this week Monday'));
        //周日
        $weekEt = date("Ymd", strtotime('this week Sunday'));



        $str_month = date("Ym");
        $str_day = date("Ymd");
        $first = 1;
        $w = date('w', strtotime($str_day));
        $str_week_start = date('Ymd', strtotime("$str_day -" . ($w ? $w - $first : 6) . ' days'));
        $str_week_end = date('Ymd', strtotime("$str_week_start +6 days"));
        $user_day_key = $this->redis_charts_user_charm_day . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month . $str_month;
        $user_all_key = $this->redis_charts_user_charm_all;
        $maximumGoldRoomIds = (new MaximumGoldRoomServices())->getRoomIds();
        if ($room_id && $maximumGoldRoomIds && in_array($room_id, $maximumGoldRoomIds)) {// 最多金榜单
            $user_day_key = $this->redis_charts_user_charm_day_maximum_gold . $str_day;
            $user_week_key = $this->redis_charts_user_charm_week_maximum_gold . $str_week_start . $str_week_end;
            $user_month_key = $this->redis_charts_user_charm_month_maximum_gold . $str_month;
            // $user_all_key = $this->redis_charts_user_charm_all_maximum_gold;
        }

        Redis::zincrby($user_day_key, $charm_value, $user_id);
        Redis::zincrby($user_week_key, $charm_value, $user_id);
        Redis::zincrby($user_month_key, $charm_value, $user_id);
        Redis::zincrby($user_all_key, $charm_value, $user_id);
        // $this->inc_user_total_score($user_id);
        // if(Redis::TTL($user_day_key) == -1){
        Redis::EXPIRE($user_day_key, 2 * 24 * 3600);
        // }
        // if(Redis::TTL($user_week_key) == -1){
        Redis::EXPIRE($user_week_key, 2 * 7 * 24 * 3600);
        // }
        // if(Redis::TTL($user_month_key) == -1){
        Redis::EXPIRE($user_month_key, 2 * 31 * 24 * 3600);
        // }

        if (empty($room_id)) {
            return true;
        }

        //更新房间魅力榜单
        $cacheExpire = 7 * 86400;
        //日榜
        $dayKey = $this->redis_charts_room_user_charm_day . $room_id . ':' . $ymdNow;
        Redis::zincrby($dayKey, $charm_value, $user_id);
        Redis::expire($dayKey, $cacheExpire);
        //周榜
        $weekDay = $this->redis_charts_room_user_charm_week . $room_id . ':' . $weekSt . ':' . $weekEt;
        Redis::zincrby($weekDay, $charm_value, $user_id);
        Redis::expire($weekDay, $cacheExpire);
    }


    /**
     * 获取魅力值排行榜
     * @param $type 1.天 2.周 -.月 3.总
     * @param $index
     * @param $count
     * @return array
     */
    public function get_user_charts($type, $index, $count)
    {
        $str_month = date("Ym");
        $str_day = date("Ymd");
        $first = 1;
        $w = date('w', strtotime($str_day));
        $str_week_start = date('Ymd', strtotime("$str_day -" . ($w ? $w - $first : 6) . ' days'));
        $str_week_end = date('Ymd', strtotime("$str_week_start +6 days"));
        $user_day_key = $this->redis_charts_user_charm_day . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month . $str_month;
        $user_all_key = $this->redis_charts_user_charm_all;

        $key = $user_day_key;

        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }
        return Redis::zrevrange($key, $index, $index + $count - 1, 'withscores');
    }

    /**
     * 获取人气排行榜-最多金
     * @param $type 1.天 2.周 -.月 3.总
     * @param $index
     * @param $count
     * @return array
     */
    public function get_user_charts_maximum_gold($type, $index, $count)
    {
        $str_month = date("Ym");
        $str_day = date("Ymd");
        $first = 1;
        $w = date('w', strtotime($str_day));
        $str_week_start = date('Ymd', strtotime("$str_day -" . ($w ? $w - $first : 6) . ' days'));
        $str_week_end = date('Ymd', strtotime("$str_week_start +6 days"));
        $user_day_key = $this->redis_charts_user_charm_day_maximum_gold . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week_maximum_gold . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month_maximum_gold . $str_month;
        $key = $user_day_key;
        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }

        return Redis::zrevrange($key, $index, $index + $count - 1, 'withscores');
    }


    /**
     * 获取房间魅力值排行榜
     * @param $type 1.天 2.周 -.月 3.总 4昨日 5上周
     * @param $room_id
     * @param $index
     * @param $count
     * @return mixed
     */
    public function get_room_user_charts($type, $room_id, $index, $count)
    {
        $now = time();
        //今日
        $ymdNow = date("Ymd", $now);
        //周一
        $startWeek = Carbon::today()->startOfWeek();
        $weekSt = date("Ymd", strtotime($startWeek));
        //周日
        $weekEt = date("Ymd", strtotime('this week Sunday'));
        //昨日
        $yestorday = Carbon::yesterday()->toDateString();
        $room_user_yestorDay_key = $this->redis_charts_room_user_charts_yestorday . $room_id . ':' . $yestorday;
        //上周
        // 获取上周的开始日期（周一）
        $startOfLastWeek = Carbon::now()->subWeek()->startOfWeek()->toDateString();

        // 获取上周的结束日期（周日）
        $endOfLastWeek = Carbon::now()->subWeek()->endOfWeek()->toDateString();
        $room_user_lastweek_key = $this->redis_charts_room_user_charts_lastweek . $room_id . ':' . $startOfLastWeek . '|' . $endOfLastWeek;

        if ($type == 1) {
            $key = $this->redis_charts_room_user_charm_day . $room_id . ':' . $ymdNow;
        }

        if ($type == 2) {
            $key = $this->redis_charts_room_user_charm_week . $room_id . ':' . $weekSt . ':' . $weekEt;
        }
        if ($type == 3) {
            $key = $this->redis_charts_room_user_charm_all . $room_id;
        }
        if ($type == 4) {
            $key = $room_user_yestorDay_key;
        }
        if ($type == 5) {
            $key = $room_user_lastweek_key;
        }
        if (empty($key)) {
            return [];
        }

        return Redis::zrevrange($key, $index, $index + $count - 1, 'withscores');
    }


    //获取距离最近的魅力等级
    public function getNearCharmRank($charm_balance)
    {
        if (empty($charm_balance)) {
            $charm_balance = 0;
        }
        $table_finance_charm_rank = $this->tablePrefix . 'finance_charm_rank';
        $document = DB::select("select rank_id,rank_pid,rank_name,image,charm_to_kk,small_image from $table_finance_charm_rank where rank_pid = 0 and $charm_balance >= min_value and IF(max_value = 0,1,$charm_balance <= max_value) limit 1");
        $result = self::objToArray($document);
        for ($i = 0; $i < count($result); $i++) {
            $result[$i]['image'] = $result[$i]['image'] ? getPicDomain() . $result[$i]['image'] : "";
            $result[$i]['small_image'] = $result[$i]['small_image'] ? getPicDomain() . $result[$i]['small_image'] : "";
        }
        if (isset($result[0]) && !empty($result)) {
            return $result[0];
        }
        return $result;
    }



    //魅力值等级明细
    public function getCharmRankData()
    {
        $condition = [];
        $fields = ['rank_id', 'rank_pid', 'rank_name', 'image', 'min_value', 'max_value', 'small_image', 'level', 's_small_image'];
        $document = DB::table('finance_charm_rank')
            ->where($condition)
            ->orderBy('min_value', 'asc')
            ->get($fields);

        $result = self::objToArray($document);
        foreach ($result as $key => $val) {
            $val['image'] = empty($val['image']) ? "" : getPicDomain() . $val['image'];
            $val['small_image'] = empty($val['small_image']) ? "" : getPicDomain() . $val['small_image'];
            $val['s_small_image'] = empty($val['s_small_image']) ? "" : getPicDomain() . $val['s_small_image'];
            $sub_rank = $val;
            unset($sub_rank['rank_id'], $sub_rank['rank_pid']);
            $val['sub_rank'][] = $sub_rank;
            $result[$key] = $val;
        }

        return $result;
    }


    /**
     * 获取用户魅力值百分比
     * @param $user_id
     */
    public function getUserFinanceCharmRank($user_id)
    {
        $wallet = DB::table('finance_wallet')
            ->where('user_id', '=', $user_id)
            ->first(['charm_balance']);

        $wallet = self::objToArray($wallet);

        $walletCount = DB::table('finance_wallet')
            ->count(['charm_balance']);

        $walletRankCount = DB::table('finance_wallet')
            ->where('charm_balance', '<', $wallet['charm_balance'])
            ->count(['charm_balance']);

        if ($wallet) {
            return intval(($walletRankCount / $walletCount) * 100);
        }

        return 0;

    }

    public function set_user_rank($user_id, $rank_id)
    {
        Redis::HSET($this->redis_finance_user_charm_rank, $user_id, $rank_id);
    }

    public function get_user_rank($user_id)
    {
        return Redis::HGET($this->redis_finance_user_charm_rank, $user_id);
    }

    /**更新当前的魅力值到总魅力值
     * @param $user_id
     */
    public function inc_user_total_score($user_id)
    {
        if (time() >= 1606060800 && time() < 1607270400) {
            $key = $this->redis_charts_user_charm_day . date('Ymd');
            $today_score = Redis::zscore($key, $user_id) ?? 0;
            $before_score = Redis::zscore($this->redis_finance_user_charm_before_total, $user_id) ?? 0;
            Redis::zadd($this->redis_finance_user_charm_total, $today_score + $before_score, $user_id);
        }
    }

    /**获取前20名的总魅力榜单
     * @param $start 开始
     * @param $end 结束
     * @return mixed
     */
    public function get_user_total_score($start, $end)
    {
        return Redis::zrevrange($this->redis_finance_user_charm_total, $start, $end, 'withscores');
    }

    /**
     * 获取魅力值排行榜
     * @param $type 1.天 2.周 -.月 3.总
     * @param $index
     * @param $count
     * @return array
     */
    public function get_before_user_charts($type, $index = 0, $count = 3)
    {
        $str_month = date("Ym", strtotime("-1 month"));
        $str_day = date("Ymd", strtotime("-1 day"));
        $str_week_start = date("Ymd", strtotime('monday last week'));
        $str_week_end = date("Ymd", strtotime('monday this week - 1 days'));
        $user_day_key = $this->redis_charts_user_charm_day . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month . $str_month;
        $user_all_key = $this->redis_charts_user_charm_all;

        $key = $user_day_key;

        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }
        return Redis::zrevrange($key, $index, $index + $count - 1, 'withscores');
    }

    public function get_before_my_chart($type, $user_id)
    {
        $str_month = date("Ym", strtotime("-1 month"));
        $str_day = date("Ymd", strtotime("-1 day"));
        $str_week_start = date("Ymd", strtotime('monday last week'));
        $str_week_end = date("Ymd", strtotime('monday this week - 1 days'));
        $user_day_key = $this->redis_charts_user_charm_day . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month . $str_month;

        $key = $user_day_key;

        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }

        return Redis::zscore($key, $user_id) ?? 0;
    }

    /**
     * 获取人气排行榜-最多金
     * @param $type 1.天 2.周 -.月 3.总
     * @param $index
     * @param $count
     * @return array
     */
    public function get_before_user_charts_maxmium_gold($type, $index = 0, $count = 3)
    {
        $str_month = date("Ym", strtotime("-1 month"));
        $str_day = date("Ymd", strtotime("-1 day"));
        $str_week_start = date("Ymd", strtotime('monday last week'));
        $str_week_end = date("Ymd", strtotime('monday this week - 1 days'));
        $user_day_key = $this->redis_charts_user_charm_day_maximum_gold . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week_maximum_gold . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month_maximum_gold . $str_month;
        $key = $user_day_key;
        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }
        return Redis::zrevrange($key, $index, $index + $count - 1, 'withscores');
    }

    /**
     * 根据用户id 获取魅力值
     * @param $type 1.天 2.周 -.月 3.总
     * @param $user_id
     * @return mixed
     */
    public function get_my_chart($type, $user_id)
    {
        $str_month = date("Ym");
        $str_day = date("Ymd");
        $first = 1;
        $w = date('w', strtotime($str_day));
        $str_week_start = date('Ymd', strtotime("$str_day -" . ($w ? $w - $first : 6) . ' days'));
        $str_week_end = date('Ymd', strtotime("$str_week_start +6 days"));
        $user_day_key = $this->redis_charts_user_charm_day . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month . $str_month;

        $key = $user_day_key;

        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }

        return Redis::zscore($key, $user_id) ?? 0;
    }

    /**
     * 根据用户id 获取魅力值-最多金
     * @param $type 1.天 2.周 -.月 3.总
     * @param $user_id
     * @return mixed
     */
    public function get_my_chart_maximum_gold($type, $user_id)
    {
        $str_month = date("Ym");
        $str_day = date("Ymd");
        $first = 1;
        $w = date('w', strtotime($str_day));
        $str_week_start = date('Ymd', strtotime("$str_day -" . ($w ? $w - $first : 6) . ' days'));
        $str_week_end = date('Ymd', strtotime("$str_week_start +6 days"));
        $user_day_key = $this->redis_charts_user_charm_day_maximum_gold . $str_day;
        $user_week_key = $this->redis_charts_user_charm_week_maximum_gold . $str_week_start . $str_week_end;
        $user_month_key = $this->redis_charts_user_charm_month_maximum_gold . $str_month;
        $key = $user_day_key;
        if ($type == 1) {
            $key = $user_day_key;
        }

        if ($type == 2) {
            $key = $user_week_key;
        }

        if ($type == 3) {
            $key = $user_month_key;
        }

        return Redis::zscore($key, $user_id) ?? 0;
    }

    // 获取时间段内某房间下人气流水
    public function getCharmListByRoomId($roomId, $startTime, $endTime)
    {
        $charms = DB::table('finance_charm_stream')
            ->where('room_id', '=', $roomId)
            ->where('change_timestamp', '>=', $startTime)
            ->where('change_timestamp', '<=', $endTime)
            ->select('stream_id', 'user_id', DB::raw('SUM(charm_value) as sumValue'))
            ->groupBy('user_id')
            ->get();
        return $charms;
    }
    // 修改排行缓存
    public function updateMonthCache($strMonth, $charmValue, $userId)
    {
        $userMonthKey = $this->redis_charts_user_charm_month_maximum_gold . $strMonth;
        $userMonthKeyY = $this->redis_charts_user_charm_month . $strMonth;
        $re = Redis::zincrby($userMonthKey, $charmValue, $userId);
        if (intval($re) <= 0) {
            Redis::zrem($userMonthKey, $userId);
        }
        $reY = Redis::zincrby($userMonthKeyY, 0 - $charmValue, $userId);
        if (intval($reY) <= 0) {
            Redis::zrem($userMonthKeyY, $userId);
        }
    }

    // 修改排行缓存
    public function updateWeekCache($strWeekStart, $strWeekEnd, $charmValue, $userId)
    {
        $userWeekKey = $this->redis_charts_user_charm_week_maximum_gold . $strWeekStart . $strWeekEnd;
        $userWeekKeyY = $this->redis_charts_user_charm_week . $strWeekStart . $strWeekEnd;
        $re = Redis::zincrby($userWeekKey, $charmValue, $userId);
        if (intval($re) <= 0) {
            Redis::zrem($userWeekKey, $userId);
        }
        $reY = Redis::zincrby($userWeekKeyY, 0 - $charmValue, $userId);
        if (intval($reY) <= 0) {
            Redis::zrem($userWeekKeyY, $userId);
        }
    }

    // 修改排行缓存
    public function updateDayCache($strDay, $charmValue, $userId)
    {
        $userDayKey = $this->redis_charts_user_charm_day_maximum_gold . $strDay;
        $userDayKeyY = $this->redis_charts_user_charm_day . $strDay;
        $re = Redis::zincrby($userDayKey, $charmValue, $userId);
        if (intval($re) <= 0) {
            Redis::zrem($userDayKey, $userId);
        }
        $reY = Redis::zincrby($userDayKeyY, 0 - $charmValue, $userId);
        if (intval($reY) <= 0) {
            Redis::zrem($userDayKeyY, $userId);
        }
    }

    // 修改排行缓存
    public function updateAllCache($charmValue, $userId)
    {
        $userAllKey = $this->redis_charts_user_charm_all_maximum_gold;
        $userAllKeyY = $this->redis_charts_user_charm_all;
        Redis::zincrby($userAllKey, $charmValue, $userId);
        Redis::zincrby($userAllKeyY, 0 - $charmValue, $userId);
    }
    /**
     * 修复最多金人气月榜缓存
     */
    public function updateCharmMonthChartsCache($maximumGoldRoomIds, $strMonth, $startTime, $endTime)
    {
        if (count($maximumGoldRoomIds) > 0) {// 最多金榜单
            $strDay = date("Ymd");
            $first = 1;
            $w = date('w', strtotime($strDay));
            $strWeekStart = date('Ymd', strtotime("$strDay -" . ($w ? $w - $first : 6) . ' days'));
            $strWeekEnd = date('Ymd', strtotime("$strWeekStart +6 days"));
            $userWeekKey = $this->redis_charts_user_charm_week_maximum_gold . $strWeekStart . $strWeekEnd;
            $userMonthKey = $this->redis_charts_user_charm_month_maximum_gold . $strMonth;
            foreach ($maximumGoldRoomIds as $k => $v) {
                $roomId = (int) $v;
                Log::info('修复最多金人气月榜缓存:updateCharmMonthChartsCache:房间号:' . $roomId);
                if ($roomId <= 0) {
                    Log::info('修复最多金人气月榜缓存:updateCharmMonthChartsCache:房间号:' . $roomId . '没有记录');
                    continue;
                }
                $wealthValue = DB::table('finance_charm_stream')
                    ->where('room_id', '=', $roomId)
                    ->where('change_time', '>=', $startTime)
                    ->where('change_time', '<=', $endTime)
                    ->select('stream_id', 'room_id', 'user_id', 'charm_value')
                    ->orderBy('stream_id', 'asc')
                    ->get();
                if (count($wealthValue) <= 0) {
                    Log::info('修复最多金人气月榜缓存:updateCharmMonthChartsCache:房间号:' . $roomId . '没有流水');
                    continue;
                }
                foreach ($wealthValue as $k => $v) {
                    Log::info('修复最多金人气月榜缓存:updateCharmMonthChartsCache:流水ID:' . $v->stream_id);
                    Redis::zincrby($userMonthKey, $v->charm_value, $v->user_id);
                    if (strtotime($strWeekStart . ' 00:00:00') >= strtotime($v->change_time)) {
                        Redis::zincrby($userWeekKey, $v->charm_value, $v->user_id);
                        $userWeekKeyY = $this->redis_charts_user_charm_week . $strWeekStart . $strWeekEnd;
                        Redis::zincrby($userWeekKeyY, 0 - ($v->charm_value), $v->user_id);
                    }
                    $userMonthKeyY = $this->redis_charts_user_charm_month . $strMonth;
                    $userAllKeyY = $this->redis_charts_user_charm_all;
                    Redis::zincrby($userMonthKeyY, 0 - ($v->charm_value), $v->user_id);
                    Redis::zincrby($userAllKeyY, 0 - ($v->charm_value), $v->user_id);
                }
            }
        }
    }

    /**
     * 检测房间魅力榜是否存在 补数据
     * @param $room_user_week_key
     * @param $room_id
     * @param $str_week_start
     * @param $str_week_end
     */
    public function checkRoomChartUserWeek($room_user_week_key, $room_id, $str_week_start, $str_week_end, $log_id = 0)
    {
        if (!Redis::EXISTS($room_user_week_key)) {
            if (!$log_id) {
                $log_id = $this->getlastChamIdByRoom($room_id);
                if ($log_id) {
                    $log_id++;
                } else {
                    return true;
                }
            }
            if ($this->redis_lock($room_user_week_key, 5)) {
                $str_week_start = date('Y-m-d 00:00:00', strtotime($str_week_start));
                $str_week_end = date('Y-m-d H:i:s');
                $data = $this->getRoomCharmBroad($room_id, $str_week_start, $str_week_end, $log_id);
                foreach ($data as $value) {
                    $charm_total = intval($value['charm_total'] * 10);
                    Redis::zincrby($room_user_week_key, $charm_total, $value['user_id']);
                }
                if (Redis::TTL($room_user_week_key) == -1) {
                    Redis::EXPIRE($room_user_week_key, 2 * 7 * 24 * 3600);
                }
            }
        }
        return true;

    }

    public function getRoomCharmBroad($room_id, $str_start, $str_end, $log_id)
    {
        $data = DB::table($this->table)
            ->whereBetween('change_time', [$str_start, $str_end])
            ->where('room_id', $room_id)
            ->where('stream_id', '<', $log_id)
            ->where('charm_type', '<>', 21)
            ->groupBy('user_id')
            ->select('user_id', DB::raw('sum(charm_value) as charm_total'))
            ->get();
        return $this->objToArray($data);
    }

    public function getlastChamIdByRoom($room_id)
    {
        return DB::table($this->table)
            ->where('room_id', $room_id)
            ->max('stream_id');
    }


    /**
     * Redis 锁 type 1:手动解锁 2：超时解锁
     * @param $key
     * @param int $lockExpire
     * @return bool
     */
    function redis_lock($key, $lockExpire = 3)
    {
        $lockKey = 'lock:' . $key;

        $lockValue = time() + $lockExpire;

        $ret = Redis::setnx($lockKey, $lockValue);
        if (!$ret) {
            return false;
        }
        Redis::expire($lockKey, $lockExpire);
        return true;

    }

}
